package com.arraymasterx.aspect;

import com.arraymasterx.config.AlgorithmConfig;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AlgorithmPerformanceAspect {

    private static final Logger logger = LoggerFactory.getLogger(AlgorithmPerformanceAspect.class);

    private final AlgorithmConfig algorithmConfig;

    @Autowired
    public AlgorithmPerformanceAspect(AlgorithmConfig algorithmConfig) {
        this.algorithmConfig = algorithmConfig;
    }

    @Around("execution(* com.arraymasterx.algorithm..*.*(..))")
    public Object logAlgorithmPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().getName();
        String className = joinPoint.getTarget().getClass().getSimpleName();

        long startTime = System.nanoTime();
        Object result = joinPoint.proceed();
        long endTime = System.nanoTime();

        long durationMs = (endTime - startTime) / 1_000_000;

        if (algorithmConfig.getPerformance().isLogAll()
                || durationMs > algorithmConfig.getPerformance().getWarningThresholdMs()) {

            logger.info("Algorithm {}.{} executed in {} ms", className, methodName, durationMs);

            if (durationMs > algorithmConfig.getPerformance().getWarningThresholdMs()) {
                logger.warn("Algorithm {}.{} took {} ms - consider optimization", className, methodName, durationMs);
            }
        }

        return result;
    }
}